home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * ispCODE.c *
- * ispCODE for ispLSI Devices Using the Industry Standard ISP State Machine *
- * and for ispLSI Devices Using the JTAG TAP controller. *
- * Lattice Semiconductor Corp. Copyright 1996,1997. *
- * *
- * ISP(tm) daisy chain turbo programming is supported by ispCODE. *
- * *
- * The function of this ispCODE is to utilize the Industry Standard ISP state *
- * machine in the ispLSI devices or the JTAG TAP for programming and *
- * verification. The input file for ispCODE is FULL ispSTREAM files or Super *
- * FULL ispSTREAM files. This file is obtained by combining the file icode5a.c*
- * particularily for ISP chain configuration and the file icode5c.c for *
- * ispJTAG chain configuration. The program is compiled as xturbo.exe for *
- * programming demonstration on PC. This program is also provided so that *
- * it can be used as a command line production programming program on PC. *
- * As such the elaborate scheme to ensure correct programming pulse on PC is *
- * retained on the pulse_width() function. *
- * *
- * This version of ispCODE is the much simplified version of ispCODE V3.xx *
- * by removing the PES checking, the post BULK ERASE verification and the *
- * simultaneous shifting data in and out. The programming time is thus a bit *
- * longer than V3.xx due to the additional time needed to shift data in and *
- * out separately. It is a very little price to pay for a 50% reduction in *
- * code size which is especially critical for embedded controller programming *
- * where resources is extremely limited. *
- * *
- * The file size of Super FULL ispSTREAM is about 30% less than the FULL *
- * ispSTREAM. The saving comes from replacing long chain of 0xFFs with *
- * the number of consecutive 0xFF bytes. For example: *
- * 0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x03,0xC3 *
- * *
- * The Super FULL ispSTREAM file is created by the command line program *
- * dld2isp.exe v4.03 with the option sf selected. For example: type *
- * dld2isp design.dld sf *
- * *
- * All ispLSI devices support the Lattice Semiconductor pioneered UES *
- * feature. If the UES is appended into the JEDEC files using the UES editor *
- * on ISP Daisy Chain Download program, the resultant ispSTREAM will take *
- * care of programming and verifying the UES data. *
- * *
- * Note: The UES length of most ispLSI devices is the same as their data *
- * length. If it is found on the data book that they are not the same *
- * such as ispLSI 3256 and 6192 devices, only the last 160 bits are *
- * referred to as UES. For example: The data length of ispLSI 3256 *
- * devices is 338 bits and the UES length is 160 bits as shown in the *
- * data book. Pulse SCLK 338-160=178 times to flush out the phantum *
- * bits first then read the 1st UES bit. *
- * *
- * Revision history: *
- * 5.000 Howard Tang 01/08/97 Created by combining ispcode.c V3.0x, *
- * icode5a.c and icode5c.c. *
- * 5.001 Howard Tang 01/17/97 Fixed bugs on supporting 3256E,3160 & GDX *
- * devices. *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <dos.h>
- #include <stdlib.h>
- #include <string.h>
- #include "lattice.h"
-
- /*Global variables */
- static short int jtag=0; /*the flag is true if ispJTAG chain*/
- static short int bit=0; /*the current bit read from ispSTREAM*/
- static unsigned char curch; /*the current data from ispSTREAM*/
- FILE *fp; /*the pointer to the ispSTREAM file*/
- static short int inputport=inport1, /*port address for the input port*/
- outputport=outport1; /*port address for the output port*/
- static short int isp_pins=NUL; /*3.02 holds the value of parallel port*/
- /* intialized to drive all pins to LOW*/
- static char state; /*4.0 Keep track of the state of the TAP
- state machine.*/
-
- /*prototypes*/
- void pulse_width(unsigned int milliseconds);
- void execute(void);
- void move_to_id_state(void);
- short int ispstream_pump(short int operation, short int *end);
- void error_handler(short int rcode, char *message);
- unsigned char GetByte(void);
- void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse,
- short int *ProgramPulse, short int *RowLength,
- unsigned short int *DataSize,
- unsigned short int *IDStreamLength);
- char ispRead(unsigned short int DataSize, unsigned char *OutData);
- void ReadispSTREAMDataSize(unsigned short int *DataSize);
- void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
- char SF);
- char ispInstruction(char SF,char Send);
- void ispData( unsigned char *InData, unsigned short int DataSize);
- void program_enable(short int chips);
- void device_enable(short int chips);
-
- /***************************************************************************
- Function: isp_setpin(byte pins, byte value)
-
- Purpose:
- To apply the specified value to the pins indicated. This routine will
- likely be modified for specific systems. As an example, this code
- is for the PC, as described below.
-
- This routine uses the IBM-PC standard Parallel port, along with the
- schematic shown in Lattice documentation, to apply the signals to the
- programming loop.
-
- PC Parallel port pin Signal name
- -------------------- -----------
- 2 out_SDI
- 3 out_SCLK
- 4 out_MODE
- 5 out_ISP
- 6 out_RESET
- 7 DO5
- 8 out_SENSE_CABLE_OUT
- 9 DO7
- 10 in_SDO
- 12 in_CABLE_SENSE_IN
- 15 in_VCC_OK
- 20 GND
-
- Parameters:
- - pins, which is actually a set of bit flags (defined in lattice.h)
- that correspond to the bits of the data port. Each of the I/O port
- bits that drives an isp programming pin is assigned a flag
- (through a #define) corresponding to the signal it drives. To
- change the value of more than one pin at once, the flags are added
- together, much like file access flags are.
-
- The bit flags are only set if the pin is to be changed. Bits that
- do not have their flags set do not have their levels changed. The
- state of the port is always manintained in the static global
- variable isp_pins, so that each pin can be addressed individually
- without disturbing the others.
-
- - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
- values are valid. Any non-zero number sets the pin(s) high.
-
- Returns: nothing.
-
-
- **************************************************************************/
- void isp_setpin(unsigned char pins, unsigned char value)
- {
- /* isp_pins is a Global value that keeps track of the current state
- of the pins */
-
- if( value ) /* set flagged pins HIGH */
- isp_pins = pins | isp_pins;
- else /* set flagged pins LOW */
- isp_pins = ~pins & isp_pins;
-
- /* value is put on Parallel port pins */
- outp(outputport, isp_pins);
-
- } /* isp_setpin() */
-
-
- /***************************************************************************
- Function: isp_SDO()
-
- Purpose:
- To get the value of the SDO pin from the input port.
-
- This routine is specific to the PC parallel port setup, but can easily
- be changed to address each user's hardware.
-
- Parameters: none
-
- Returns: The value of SDO, as a byte, with a value of either 0 or 1.
-
- Notes:
- - This routine uses the I/O port addresses contained in the global
- variable inputport, declared in the lattice.h file.
-
-
- ****************************************************************************/
- unsigned char isp_SDO(void)
- {
- /* MUST return either 0x00 or 0x01 */
- return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
-
- } /* isp_SDO() */
-
-
- /*************************************************************
- * *
- * PULSE_WIDTH *
- * *
- *************************************************************/
-
-
- void pulse_width(unsigned int milliseconds)
- {
- static unsigned int ticks_per_ms = 0;
- static int mode2 = false;
- static long pre_ticks = 0L;
- unsigned int start,
- end;
- long ticks,
- cur_ticks;
- static int count = 0;
-
-
- cur_ticks = 0L;
- outp(0x43, 0x00);
- start = inp(0x40);
- start += inp(0x40) << 8;
- if (ticks_per_ms == 0) {
- ticks_per_ms = (0xFFFF / 55) * 2;
- if (start & 0x0001) {
- ticks_per_ms = 0xFFFF / 55;
- mode2 = true;
- }
- }
- ticks = (long) ticks_per_ms *milliseconds;
- while (ticks > 0L) {
- if (pre_ticks == 0L)
- pre_ticks = cur_ticks;
- else if (count < 5) { /* calibration count *//* keep
- * the most conservative ticks
- * per loop as calibrated
- * value */
- if (pre_ticks > cur_ticks)
- pre_ticks = cur_ticks;
- count++;
- }
- outp(0x43, 0x00);
- end = inp(0x40);
- end += inp(0x40) << 8;
- if ((!mode2) && (end & 0x0001)) {
- ticks_per_ms = 0xFFFF / 55;
- ticks -= (long) ticks_per_ms *milliseconds;
- mode2 = true;
- if (ticks <= 0L)
- break; /* done already */
- }
- cur_ticks = (long) (start - end); /* number of ticks elapsed */
- if (cur_ticks == 0L) { /* this can happen only when
- * in Window DOS */
- cur_ticks = pre_ticks;
- ticks -= cur_ticks;
- } else if (cur_ticks > 0L)
- ticks -= cur_ticks;
- else {
- cur_ticks = (long) (0xFFFF - end + start);
- ticks -= cur_ticks;
- }
- /* safe guard against stolen ticks in Window DOS */
- if ((pre_ticks > 0L) && ((cur_ticks - pre_ticks) > (ticks_per_ms / 4))) {
- ticks += (cur_ticks - pre_ticks);
- cur_ticks = pre_ticks;
- }
- start = end;
- }
- }
-
-
-
-
- /*************************************************************
- * *
- * GETBYTE *
- * This procedure reads a byte from the ispSTREAM. *
- *************************************************************/
- unsigned char GetByte()
- {
- return (fgetc(fp));
- }
-
-
- /*************************************************************
- * *
- * SCLOCK *
- * This procedure apply a clock to TCK. *
- *************************************************************/
- void sclock(void)
- {
- isp_setpin(out_SCLK,HIGH);
- isp_setpin(out_SCLK,LOW);
- }
-
- /*************************************************************
- * *
- * SHIFT/EXECUTE *
- * This procedure walk all devices in the daisy chain from a *
- * given state to the next desirable state. *
- * *
- *If at Idle state when enter then move to Shift-IR state. *
- *If at Shift-IR state when enter then move to Shift-DR state.*
- *If at Shift-DR state when enter then move to Shift-IR state.*
- *If at Shift-IR state and state is set to time_state when *
- *enter then move to Idle state. *
- *************************************************************/
- void execute()
- {
- short int i,count;
- /*for ISP chain*/
- if (!jtag)
- {isp_setpin(out_MODE, HIGH);
- isp_setpin(out_SDI, HIGH);
- sclock();
- isp_setpin(out_SDI, LOW);
- isp_setpin(out_MODE, LOW);
- return;
- }
- /*for ispJTAG chain*/
- if (state==time_state)
- {count = 1; /*move from shift-IR to Idle state to start timing*/
- state = idle_state;
- }
- else if (state==shift_state)
- {count = 2; /*move from shift-IR to shift-DR*/
- state = execute_state;
- }
- else if (state==idle_state)
- {count = 2; /*move from Idle to shift-IR state*/
- state = shift_state;
- }
- else if (state==execute_state)
- {count = 3; /*move from shift-DR to shift-IR*/
- state = shift_state;
- }
- else count = 0;
- isp_setpin(out_SCLK,LOW);
- isp_setpin(out_MODE,LOW);
- isp_setpin(out_SDI,LOW);
- for (i=0; i<count; i++)
- {
- isp_setpin(out_MODE,HIGH);
- sclock();
- }
- isp_setpin(out_MODE,LOW);
- sclock();
- if (count > 1) sclock();
- /* at Shift-DR or Shift-IR state*/
- }
-
-
- /*************************************************************
- * *
- * MOVE TO ID STATE *
- * This procedure walk all devices in the daisy chain to the *
- * Test-Logic-Reset state then Run-Test/Idle state. *
- * *
- *************************************************************/
-
- void move_to_id_state()
- {
- int i;
- isp_setpin(out_SCLK,LOW);
- isp_setpin(out_MODE+out_SDI,LOW);
- pulse_width(2);
- isp_setpin(out_MODE,HIGH);
- pulse_width(2);
- isp_setpin(out_SCLK,HIGH);
- pulse_width(2);
- isp_setpin(out_SCLK,LOW);
- for (i=0; i<6; i++) sclock();
- isp_setpin(out_MODE,LOW);
- pulse_width(2);
- if (!jtag) return; /*skip if ISP chain*/
- sclock(); /*device is in Idle state*/
- state = idle_state;
- }
-
- /*************************************************************
- * *
- * PROGRAM ENABLE *
- * perform the 3 read id instruction to get devices into *
- * programming mode. *
- *************************************************************/
-
- void program_enable(short int chips)
- {
- short int i,j,loops;
-
- if (!jtag) return; /*skip for ISP chain*/
- for (loops=0; loops<3; loops++)
- {
- for (i=0; i<chips+1; i++)
- for (j=0; j<5; j++) /*send the instruction into TDI*/
- {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH); /*last bit*/
- isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
- sclock();
- }
- for (i=0; i<3; i++) sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock(); /*devices at Shift-IR state*/
-
- }
- }
-
- /*************************************************************
- * *
- * DEVICE ENABLE *
- * perform the read id instruction to get devices into *
- * functional mode. *
- *************************************************************/
-
- void device_enable(short int chips)
- {
- short int i,j;
-
- if (!jtag) return; /*skip for ISP chain*/
- /*devices come in at Shift-IR state*/
- for (i=0; i<chips+1; i++)
- for (j=0; j<5; j++) /*send the instruction into TDI*/
- {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH); /*last bit*/
- isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
- sclock();
- }
- sclock(); /*devices at Update-IR state*/
- isp_setpin(out_MODE,LOW);
- for (i=0; i<20; i++) sclock(); /*go and loop on Run-Test/Idle for 10uS*/
- isp_setpin(out_MODE,HIGH);
- for (i=0; i<3; i++) sclock(); /*devices at Test-Logic-Reset and active*/
- }
-
- /**********************************************************************
- * *
- * READ_ISPSTREAM_HEADER *
- * Extract the header from the ispSTREAM file. *
- * Return *
- * ChainLength--------number of ispLSI devices in the *
- * given daisy chain. *
- * ErasePulse---------pulse width in mS for device *
- * bulk erase. *
- * ProgramPulse-------pulse width in mS for device *
- * row by row programming. *
- * RowLength----------the number of rows of data +UES *
- * DataSize-----------the largest size of each row of data. *
- * BEVend-------------the end of Bulk Erase verify. *
- ***********************************************************************/
- void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse,
- short int *ProgramPulse, short int *RowLength,
- unsigned short int *DataSize,
- unsigned short int *BEVend)
- {
-
- *ChainLength = GetByte();
- *ErasePulse = GetByte() * 0x100;
- *ErasePulse += GetByte();
- *ProgramPulse = GetByte();
- *RowLength = GetByte() * 0x100;
- *RowLength += GetByte();
- *DataSize = GetByte() * 0x100;
- *DataSize += GetByte();
- *BEVend = GetByte() * 0x100;
- *BEVend += GetByte();
- /*End of the header of the ispSTREAM file.*/
-
- }
-
- /*********************************************************************
- * *
- * READ_ISPSTREAM_DATA_SIZE *
- * Extract the data size of the current row from the ispSTREAM file. *
- * Return *
- * DataSize-----------The data bit length of the current row. *
- **********************************************************************/
- void ReadispSTREAMDataSize(unsigned short int *DataSize)
- {
- short int index;
- unsigned short int temp;
- unsigned char xch;
-
- xch=0;
- temp = 0;
- for (index=0; index<16; index++)
- {--bit;
- if (bit<0)
- {
- curch = GetByte();
- bit=7;
- }
- if ((curch >> bit) & 0x01) xch |= 0x80 >> index%8;
- if (index%8==7) {temp = temp * 0x100 + xch; xch=0;}
- }
- *DataSize = temp;
- }
-
- /*****************************************************************
- * *
- * READ_ISPSTREAM_DATA *
- * Extract the data from the ispSTREAM file. *
- * SF-----------------Super FULL ispSTREAM file if true. *
- * Return *
- * DataSize-----------The number of data bits fetched. *
- * InData-------------The data stream from ispSTREAM file *
- ******************************************************************/
- void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
- char SF)
- {
- unsigned short int index,size;
- short int j;
- unsigned char xch;
- short int FFcount=0;
-
-
- ReadispSTREAMDataSize(&size);
- if (size > 0) /*5.001 retain the old size if the current row is NULL*/
- *DataSize = size;
- j=0;
- xch=0;
- for (index=0; index<size; index++)
- {--bit;
- if (bit<0)
- {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
- { curch = GetByte();
- if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
- FFcount = GetByte(); /*The number of 0xFF bytes*/
- }
- else FFcount--; /*Use up the 0xFF chain first*/
- bit=7;
- }
- if ((curch >> bit) & 0x01) xch |= 0x80 >> index%8;
- if (index%8==7) {InData[j++] = xch; xch=0;}
- }
- if (size > 0) InData[j] = xch; /*save the last byte of the current row*//*5.001*/
- }
-
- /*****************************************************************
- * *
- * ispInstruction *
- * Extract the instruction from the ispSTREAM file and clock into *
- * the devices or throw away. *
- * SF-----------------Super FULL ispSTREAM file if true. *
- * Send---------------Send data to devices if true. *
- * Return *
- * NONE *
- ******************************************************************/
- char ispInstruction(char SF, char Send)
- {
- unsigned short int index;
- short int i;
- unsigned short int size;
- short int FFcount=0;
-
- #ifdef DEBUG
- printf("\n");
- #endif
- ReadispSTREAMDataSize(&size);
- for (index=0; index<size; index++)
- {--bit;
- if (bit<0)
- {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
- { curch = GetByte();
- if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
- FFcount = GetByte(); /*The number of 0xFF bytes*/
- }
- else FFcount--; /*Use up the 0xFF chain first*/
- bit=7;
- }
- if (Send) /*send the data to the devices*/
- {isp_setpin(out_SDI,(curch >> bit) & 0x01);
- #ifdef DEBUG
- if ((curch >> bit) & 0x01) printf("1"); else printf("0");
- #endif
- if ((jtag)&&(index==size-1)) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock the data into the command registers */
- }
- }
- if ((Send)&&(size > 0))
- {execute(); /*execute the instruction if sent*/
- return (1); /*signify data or instruction has actually sent*/
- }
- else return (0); /*no data or instruction send to the devices*/
- }
-
- /**********************************************************************
- * *
- * ispData *
- * Send the data stream to devices. *
- * InData-----------The data stream to be sent to devices. *
- * DataSize---------The length of the data stream. *
- ***********************************************************************/
- void ispData(unsigned char *InData, unsigned short int DataSize)
- {
- unsigned short int index;
- short int j;
- unsigned char curch;
-
- #ifdef DEBUG
- printf("\n");
- #endif
- j=0;
- for (index = 0; index <DataSize; index++) {
- if (index%8==0) curch = InData[j++];
- isp_setpin(out_SDI, (((curch << index%8) & 0x80) ? 0x01 : 0x00));
- #ifdef DEBUG
- if ((curch << index%8) & 0x80) printf("1"); else printf("0");
- #endif
- if ((jtag)&&(index==DataSize-1)) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock data into the data shift registers */
- }
- if (DataSize> 0) execute(); /*step to shift state*//*5.001*/
- }
-
- /**********************************************************************
- * *
- * ispRead *
- * Read the data stream from devices and verify. *
- * DataSize---------The length of the data stream. *
- * OutData----------The data stream to be compare with those read *
- * from devices. *
- ***********************************************************************/
- char ispRead(unsigned short int DataSize, unsigned char *OutData)
- {
- unsigned short int index,error;
- unsigned char xch,cur_bit;
- short int j;
- #ifdef DEBUG
- printf("\n");
- #endif
- j=0;
- error=0;
- xch=0;
- for (index = 0; index <DataSize; index++) {
- if (index%8==0) xch = OutData[j++];
- cur_bit=isp_SDO();
- #ifdef DEBUG
- if (cur_bit) printf("H"); else printf("L");
- #endif
- if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00)) error++;
- if ((jtag)&&(index==DataSize-1)) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock data out from the data shift registers */
- }
- execute(); /*step to shift state*/
- if (error > 0) return 1; /*Flag failure occur*/
- else return (OK);
- }
-
- /**********************************************************************
- * *
- * ispDisplay *
- * Read the data stream from devices and display *
- * DataSize---------The length of the data stream. *
- * OutData----------The data stream read from devices. *
- * *
- * This function is for reading and displaying the UES of the ispLSI *
- * devices. If the JEDEC file of the ispLSI devices containing UES *
- * data, the UES data in the ispLSI devices will be read and displayed *
- * when calling this function. For example: *
- * 1032E pv 1032e.jed *
- * 2096 pv 2096.jed *
- * 3256A pv 3256a.jed *
- * If only the JEDEC files 1032e.jed and 2096.jed files have UES data *
- * then the UES data of 1032E and 2096 will be read and displayed as a *
- * continuous UES string. Please note that the UES of ispGAL22v10 and *
- * ispGDS can't supported by this function due to the fact that the UES*
- * are part of the ARRAY of those devices. Please also note that the *
- * actual length of UES row can be longer than what is published. *
- * For example: The UES row of 3256a is actually 338 bits long whereas *
- * the published UES length is 160. The extra bits are filled with 1s *
- * by the ispSTREAM writter. This function can read and display only *
- * the full length of the UES row. It can't mask out the dummy bits. *
- * It is strongly recommended that only one device is selected in a *
- * time in a daisy chain for reading and displaying UES. *
- ***********************************************************************/
- char ispDisplay(unsigned short int DataSize, unsigned char *OutData)
- {
- unsigned short int index;
- unsigned char xch,cur_bit;
- unsigned short int j;
- j=0;
- xch=0;
- for (index = 0; index <DataSize; index++) {
- cur_bit=isp_SDO();
- if (cur_bit) xch |= (0x80 >> index%8);
- if (index%8==7) {OutData[j++] = xch;
- xch=0;}
- if ((jtag)&&(index==DataSize-1)) isp_setpin(out_MODE,HIGH);
- sclock(); /*clock data out from the data shift registers */
- }
- OutData[j] = xch; /*store the last byte*/
- printf("\nThe UES string in HEX:\n");
- for (index = 0; index < DataSize/8; index++)
- printf("%02x",OutData[index]);
- printf("\nThe UES string in ASCII:\n");
- for (index = 0; index < DataSize/8; index++)
- {if (isprint(OutData[index])) printf("%c",OutData[index]);
- else printf(".");
- }
- printf("\n");
- execute(); /*step to shift state*/
- return (OK);
- }
-
- /*************************************************************
- * *
- * ISPSTREAM_PUMP *
- * *
- *************************************************************/
-
- short int ispstream_pump(short int operation, short int *end)
- {
- short int row;
- char SF; /*ispSTREAM file types identifier*/
- char send; /*send data to devices if true*/
- char ready; /*5.001 ready to verify data*/
- unsigned char FileType;
- short int last_row,
- erase_pulse,
- program_pulse,
- devices_in_chain;
- unsigned short int maxi_data,
- data_length,
- be_row;
- short int rcode,condition;
- unsigned char *buf;
-
- row =0;
- bit = 0;
- jtag= false;
- /*Start reading the header of the ispSTREAM file*/
- FileType = GetByte();
- if (FileType == 0xF0) {SF=false;
- jtag=true;} /*Check for correct file type*/
- else if (FileType == 0x0b ) {SF=true;
- jtag=true;} /*Super FULL ispSTREAM file found*/
- else if (FileType == 0x0F) {SF=false;} /*Check for correct file type*/
- else if (FileType == 0x0a ) {SF=true;} /*Super FULL ispSTREAM file found*/
- else {
- return FILE_NOT_JEDEC;
- }
- ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
- &last_row, &maxi_data, &be_row);
- rcode = OK; /*Success by default.*/
- if ((operation==verify)||(operation==verify_ues)
- ||(operation==read_show_ues)) /*verify only*/
- {erase_pulse=0; /*void the erase instruction*/
- program_pulse=0; /*void the program instruction*/
- }
-
- /*Allocate memory to store one row of data from the ispSTREAM file.*/
- if ((buf = (unsigned char *) malloc(maxi_data/8+1))==NULL)
- {free(buf);
- return FILE_TOO_BIG;
- }
-
- /*set the initial condition of the parallel port*/
- /* All the port_pins defined on lattice.h will be controlled by
- ispstream_pump(). The rest can be initialized here either to
- HIGH or LOW and won't be altered by isptream_pump*/
-
- isp_pins = NUL; /* intialize to drive all port pins LOW*/
- isp_setpin(out_ISP, LOW);/* drive ispEN pin low to enable the
- ispJTAG controlling pins:
- TCK,TMS,TDI and TDO.*/
- move_to_id_state(); /* Go to Reset then Run-Test/Idle state*/
- execute();
- move_to_id_state();
- if (jtag) /* for ispJTAG chain only*/
- {
- isp_setpin(out_MODE,HIGH);
- sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock();
- state=execute_state; /* At shift-DR state*/
- isp_setpin(out_SDI,HIGH);
- }
- ReadispSTREAMData(&data_length,buf,SF); /*fetch ID stream from ispSTREAM*/
- rcode = ispRead(data_length,buf); /*verify the ID stream*/
- if (rcode != OK)
- {
- if (buf != NULL)
- free(buf);
- return UNKNOWN_CHIP;
- }
- for (row=1; row<be_row; row++)
- {switch(row)
- { case 8:program_enable(devices_in_chain);/*enable programming*/
- if (erase_pulse > 0) /*erase the devices*/
- {
- state=time_state;
- ispInstruction(SF,true);
- sclock(); /*start the erase timing*/
- pulse_width(erase_pulse); /*erase pulse*/
- isp_setpin(out_MODE, HIGH);
- isp_setpin(out_SDI, HIGH);
- if (!jtag) pulse_width(1); /*super voltage discharge*/
- isp_setpin(out_SCLK,HIGH);
- if (jtag) pulse_width(1); /*super voltage discharge*/
- isp_setpin(out_SCLK,LOW);
- if (jtag) sclock();
- isp_setpin(out_SDI,LOW);
- isp_setpin(out_MODE,LOW);
- sclock(); sclock(); /*devices in shift state*/
- state=shift_state;
- }
- else ispInstruction(SF,false); /*skipp BULK ERASE*/
- break;
- default:if (((row-9)%12==3)||((row-9)%12==8)) /*skipp BULK ERASE verify*/
- ReadispSTREAMDataSize(&data_length);
- else ispInstruction(SF,false);
- break;}
- }
- /*start processing the rows in the ispSTREAM file*/
- data_length = 0;
- ready=false; /*5.001*/
- for (; row <= last_row; row++) {
- *end = row; /* The row number where process ended.*/
- if (row==last_row) condition = 8; /* security programming*/
- else condition = (row-9) % 12;
- if (((operation==verify_ues)||(operation==read_show_ues))
- &&(row <= last_row-DATAROW)) send = false;
- else send = true;
- switch(condition){
- case 0: /*address shift*/
- case 1:ispInstruction(SF,send); /*address data*/
- break;
- case 2: /*data shift*/
- case 7:ready=ispInstruction(SF,send);/*data shift*//*5.001*/
- break;
- case 3: /*shift data in/out of devices*/
- case 8:
- if ((data_length > 0)&&(ready)) /*5.001 verify the data shifted in*/
- {state=idle_state; /*loop back to Shift-DR*/
- rcode = ispRead(data_length,buf);
- if (!jtag) execute(); /*back to shift state for ISP chain*/
- state=execute_state; /*back to shift-DR state*/
- data_length=0; /*5.001 data verified*/
- }
- ReadispSTREAMData(&data_length,buf,SF); /*fetch data stream from ispSTREAM*/
- if (ready) ispData(buf,data_length); /*send data into devices*/
- break;
- case 4:
- case 9:if (program_pulse > 0) /*program and verify*/
- {
- state=time_state;
- if (ispInstruction(SF,true)) /*5.001 program commands exist*/
- {sclock(); /*start program timing*/
- pulse_width(program_pulse);
- execute(); /*step to shift state*/
- }
- state=shift_state; /*5.001 at Shift-IR*/
- }
- else ispInstruction(SF,false); /*skip programming*/
- break;
- case 5:
- case 10:state=time_state;
- if (ispInstruction(SF,send)) /*verify*/
- {sclock(); /*start verify timing*/
- pulse_width(1); /*30uS min. verify time*/
- execute(); /*step to shift state*/
- }
- state=shift_state; /*5.001 at Shift-IR*/
- break;
- case 6:
- case 11:if (ispInstruction(SF,send))
- {
- if (operation==read_show_ues) /*read and display ues*/
- rcode = ispDisplay(data_length,buf);
- else
- rcode = ispRead(data_length,buf); /*verify the data stream*/
- data_length=0; /*don't verify again*/
- }
- break;
- default:break;
- }
- if (rcode != OK) break;
- }
-
- device_enable(devices_in_chain); /*activate the devices*/
- isp_setpin(out_ISP,HIGH); /*activate the ispLSI devices*/
- if (buf != NULL) free(buf);
- if (rcode==OK)
- return (OK);
- else return VALIDATION_ERROR;
-
- }
-
-
- /*************************************************************
- * *
- * error_handler *
- * *
- * rcode - error code *
- * *
- * *
- * This procedure return the address of the message string *
- * for the corresponding error code. *
- * *
- *************************************************************/
-
- void error_handler(short int rcode, char *message)
- {
-
- char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
- {""},{""},
- {"No Device Found/Open Download Cable/Open Daisy Chain"},
- {"Can't Find the File"},{""},{"Not Enough PC Memory"},
- {"Verification Fail"},{""},{""},
- {""},
- {"The Chip Count in the Chain and the File Do Not Match"},
- {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
- {""}};
-
- strcpy(message, error_message[-rcode]);
- }
-
- /*************************************************************
- * *
- * MAIN *
- * *
- *************************************************************/
-
- int main(int argc, char *argv[])
- {
- short int rcode = OK,
- end = 0;
- char *ptr,
- filename[300],
- str[300];
- short int operation=prog_verify; /*3.05 Default to Program and Verify*/
-
-
- printf("\n Lattice Semiconductor Corp.\n");
- printf("\n ispCODE V5.00 Copyright 1997\n");
- printf("\n ispSTREAM Driver for simple ispJTAG chain or ISP chain\n\n");
-
- if ((argc < 2) || (argc > 3)) {
- printf("\nUsage: xturbo [drive:][path]isp_filename [operation] \n");
- printf("Example: xturbo my_file.isp pv\n");
- printf("\n");
- printf("isp_filename The ispSTREAM File Created From A Valid \n");
- printf(" Daisy Chain Configuration File\n");
- printf("operation \"pv\" = program and verify\n");
- printf(" \"v\" = Verify only\n");
- printf(" \"uv\" = Verify UES only\n");
- printf(" \"ud\" = Read and display UES from devices.\n");
- printf(" Default to pv if operation is not entered.\n");
- exit(1);
- }
-
- if ((fp = fopen(argv[1], "rb")) == NULL) {
- printf("\n%s File not found!\n", argv[1]);
- exit(1);
- }
-
- strcpy(str, argv[1]);
- ptr = strchr(str, '.');
- if (ptr)
- *ptr = '\0';
- sprintf(filename, "%s.isp", str);
- strcpy(str, argv[1]);
- if (stricmp(str, filename)) {
- printf("\nFile %s Is Not An ispSTREAM File\n", str);
- fclose(fp);
- exit(1);
- }
- if (rcode == OK){ /*start programming and verification*/
-
- if(!strcmp(strlwr(argv[2]),"uv")){ /*3.05 What to do? uv=ues verify only*/
- operation=verify_ues; /*for verify ues only =1*/
- printf("\nStart Verify UES of ispLSI devices.......\n");}
- else if(!strcmp(strlwr(argv[2]),"ud")){ /*ud = verify only*/
- operation=read_show_ues;
- printf("\nStart Read and Display UES of ispLSI devices .......\n");}
- else if(!strcmp(strlwr(argv[2]),"v")){ /*v = verify only*/
- operation=verify;
- printf("\nStart Verify.......\n");}
- else { /*pv = program and verify: Default*/
- operation=prog_verify;
- printf("\nStart Program and Verify.......\n");
- }
- rcode = ispstream_pump(operation, &end); /*3.05 add operation switch*/
- }
- fclose(fp);
- if (rcode != OK) {
- error_handler(rcode, str);
- printf("\nFailed At Row %d in Program and Verify Due To %s\n", end, str);
- printf("\n");
- printf("+-------+\n");
- printf("| FAIL! |\n");
- printf("+-------+\n");
- exit (-rcode);
- } else {
- printf("\n");
- printf("+=======+\n");
- printf("| PASS! |\n");
- printf("+=======+\n");
- }
-
- return (0);
- }